package com.briup.cms.service.impl;


import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.briup.cms.common.model.entity.Log;
import com.briup.cms.common.model.excel.ExcelLog;
import com.briup.cms.common.model.ext.LogExt;
import com.briup.cms.common.util.ExcelUtil;
import com.briup.cms.common.util.JsonUtil;
import com.briup.cms.common.util.ObjectUtil;
import com.briup.cms.common.util.PageUtil;
import com.briup.cms.dao.LogMapper;
import com.briup.cms.service.LogService;
import lombok.RequiredArgsConstructor;
import org.springframework.scheduling.annotation.Async;
import org.springframework.stereotype.Service;

import java.io.OutputStream;
import java.util.Date;
import java.util.List;
import java.util.Map;
import java.util.Optional;
import java.util.stream.Collectors;

/**
 * @author YuYan
 * @date 2023-12-08 14:11:59
 */
@Service
@RequiredArgsConstructor
public class LogServiceImpl implements LogService {

    private final LogMapper logMapper;

    private final JsonUtil jsonUtil;

    private final ExcelUtil excelUtil;

    @Override
    @Async
    public void save(Log log) {
        System.out.println("Service：" + Thread.currentThread().getName());
        // 假设插入日志的时候，出现了卡顿
        // try {
        //     Thread.sleep(10000);
        // } catch (InterruptedException e) {
        //     e.printStackTrace();
        // }
        logMapper.insert(log);

    }

    @Override
    public IPage<LogExt> pageQueryByClause(IPage<Log> page, LogExt logExt) {
        LambdaQueryWrapper<Log> lqw = new LambdaQueryWrapper<>();
        String username = logExt.getUsername();
        lqw.like(ObjectUtil.hasText(username), Log::getUsername, username);
        String requestUrl = logExt.getRequestUrl();
        lqw.like(ObjectUtil.hasText(requestUrl), Log::getRequestUrl, requestUrl);
        Date startTime = logExt.getStartTime();
        lqw.gt(ObjectUtil.nonNull(startTime), Log::getCreateTime, startTime);
        Date endTime = logExt.getEndTime();
        lqw.lt(ObjectUtil.nonNull(endTime), Log::getCreateTime, endTime);
        IPage<Log> logIPage = logMapper.selectPage(page, lqw);
        return PageUtil.convert(logIPage, LogExt::toExt);

    }

    @Override
    public void download(OutputStream os, LogExt logParam) {
        /* 创建一个操作对象 */
        LambdaQueryWrapper<Log> lqw = new LambdaQueryWrapper<>();
        String username = logParam.getUsername();
        lqw.like(ObjectUtil.hasText(username), Log::getUsername, username);
        String requestUrl = logParam.getRequestUrl();
        lqw.like(ObjectUtil.hasText(requestUrl), Log::getRequestUrl, requestUrl);
        Date startTime = logParam.getStartTime();
        lqw.gt(ObjectUtil.nonNull(startTime), Log::getCreateTime, startTime);
        Date endTime = logParam.getEndTime();
        lqw.lt(ObjectUtil.nonNull(endTime), Log::getCreateTime, endTime);
        int limit = logParam.getLimit();
        if (limit != -1) {
            lqw.last("limit " + limit);
        }

        /* 执行查询 */
        List<Log> logEntities = logMapper.selectList(lqw);

        List<ExcelLog> excelLogEntities = logEntities.stream()
                .map(logEntity -> {
                    /* 一个基于JSON格式的字符串值 */
                    String responseResult = logEntity.getResponseResult();
                    Map<String, Object> map = jsonUtil.parseForMap(responseResult);
                    return ExcelLog.builder()
                            .username(logEntity.getUsername())
                            .businessName(logEntity.getBusinessName())
                            .requestUrl(logEntity.getRequestUrl())
                            .requestMethod(logEntity.getRequestMethod())
                            .requestIp(logEntity.getRequestIp())
                            .spendTime(logEntity.getSpendTime())
                            .createTime(logEntity.getCreateTime())
                            .code(Optional.ofNullable(map.get("code"))
                                    .map(String::valueOf)
                                    .orElse("无数据"))
                            .message(Optional.ofNullable(map.get("message"))
                                    .map(String::valueOf)
                                    .orElse("无数据"))
                            .build();
                })
                .collect(Collectors.toList());
        excelUtil.write(os, ExcelLog.class, excelLogEntities);
    }




}
